package ru.pb.auth.network.engine.game.packets.receivable;

import java.util.ArrayList;
import java.util.List;

import ru.pb.auth.configs.AuthServerConfig;
import ru.pb.auth.data.xml.holders.GameServersHolder;
import ru.pb.auth.model.GameServerInfo;
import ru.pb.auth.model.enums.S_CHANNEL_TYPE;
import ru.pb.auth.network.engine.game.packets.FromGameServerClientToAuthServerPacket;
import ru.pb.auth.network.engine.game.packets.sendable.AUTHRESPONSE;
import ru.pb.auth.network.engine.game.packets.sendable.LOGIN_SERVER_FAIL;
import ru.pb.global.network.IPRange;
import ru.pb.global.network.utils.NetworkUtil;

public class AUTH_REQUEST extends FromGameServerClientToAuthServerPacket
{
	private int _serverId;
	private String _serverPassword;
	private boolean _isGMOnly;
	private int _serverPort;
	private int _serverMaxPlayers;
	private List<IPRange> _ipRanges;

	@Override
	public void readImpl()
	{
		_serverId = readC(); // server id
		_serverPassword = readS(32); // password
		_serverPort = readH(); // server port
		_serverMaxPlayers = readH(); // server max players
		_isGMOnly = readBoolC(); // is gm only
		int size = readD();

		_ipRanges = new ArrayList<IPRange>(size);

		for(int i = 0; i < size; i++)
			_ipRanges.add(new IPRange(readB(readC()), readB(readC()), readB(readC())));
	}

	@Override
	public void runImpl()
	{
		_log.info("Попытка зарегестрировать сервер : " + _serverId + ", " + getClient().getIPString());
		GameServerInfo gsi = GameServersHolder.getInstance().getGameServerInfo(_serverId);

		boolean isAuth = false;
		if(gsi != null)
		{
			if(_serverPassword.equals(gsi.getPassword()))
			{
				synchronized(gsi)
				{
					if(gsi.isAuthed())
						getClient().sendPacket(new LOGIN_SERVER_FAIL(LOGIN_SERVER_FAIL.REASON_ALREADY_LOGGED));
					else
					{
						if(NetworkUtil.checkIPMatching(gsi.getAllowIp(), getClient().getIPString()))
							isAuth = true;
						else
							getClient().sendPacket(new LOGIN_SERVER_FAIL(LOGIN_SERVER_FAIL.REASON_IP_BANNED));
					}
				}
			}
			else
				getClient().sendPacket(new LOGIN_SERVER_FAIL(LOGIN_SERVER_FAIL.REASON_WRONG_PASS));
		}
		else if(AuthServerConfig.ACCEPT_NEW_GAMESERVER)
		{
			gsi = new GameServerInfo(_serverId, _serverPassword, S_CHANNEL_TYPE.NORMAL.name(), getClient().getIPString());
			gsi.setIsTemp(true);
			GameServersHolder.getInstance().add(gsi);
			isAuth = true;
		}
		else
			getClient().sendPacket(new LOGIN_SERVER_FAIL(LOGIN_SERVER_FAIL.REASON_WRONG_PASS));

		if(isAuth)
		{
			AUTHRESPONSE ar = new AUTHRESPONSE(gsi.getId());

			getClient().setGameServerInfo(gsi);

			gsi.setGMOnly(_isGMOnly);
			gsi.setGameServer(getClient());
			gsi.setPort(_serverPort);
			gsi.setGameHosts(_ipRanges);
			gsi.setMaxPlayers(_serverMaxPlayers);

			gsi.setAuthed(true);
			gsi.setOnline(true);

			getClient().sendPacket(ar);

			gsi.info();
		}
		else
		{
			_log.info("Игровой сервер не может быть зарегистрирован.");
		}
	}
}